package main

import (
	"fmt"
	"math/rand"
	"sort"
	"time"
)

// 看下面一段程序，回答问题
func work1() {
	s1 := make([]int, 3, 4)
	s2 := append(s1, 1)
	fmt.Println("1.问：请问s1、s2内各有什么元素？")
	fmt.Printf("答：s1:%[1]v\n", s1)
	fmt.Printf("答：s2:%[1]v\n", s2)
	fmt.Println("2.问：s1修改一个元素会影响s2吗?s2修改一个元素会影响s1吗?")
	fmt.Println("2.答：s1和s2共用底层数组，s1修改会影响到s2，如果s2仅修改最后一个元素不会影响到s1")
	fmt.Println("3.问：s2再增加一个元素会怎么样?")
	fmt.Println("3.答：如果s2再增加一个元素扩容，那么不在共用底层数组。")
	fmt.Println("\ts1修改第一个元素：")
	s1[0] = 30
	fmt.Printf("\t\ts1 %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
	fmt.Printf("\t\ts2 %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Println("\ts2修改第一个元素：")
	s2[0] = 40
	fmt.Printf("\t\ts1 %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
	fmt.Printf("\t\ts2 %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Println("\ts1修改最后一个元素：")
	s1 = append(s1, 10)
	fmt.Printf("\t\ts1 %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
	fmt.Printf("\t\ts2 %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Println("\ts2修改最后一个元素：")
	s2 = append(s2, 20)
	fmt.Printf("\t\ts1 %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
	fmt.Printf("\t\ts2 %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Println("\ts2再增加一个元素：")
	s1[1] = 60
	s2 = append(s2, 30)
	fmt.Printf("\t\ts1 %v %p %p %d %d\n", s1, &s1, &s1[0], len(s1), cap(s1))
	fmt.Printf("\t\ts2 %v %p %p %d %d\n", s2, &s2, &s2[0], len(s2), cap(s2))
	fmt.Printf("\t\t%p %p; %d %d, %v\n", &s1, &s1[0], len(s1), cap(s1), s1)
	fmt.Printf("\t\t%p %p; %d %d, %v\n", &s2, &s2[0], len(s2), cap(s2), s2)
}

// 有一个数组 [1,4,9,16,2,5,10,15]，生成一个新切片，要求新切片元素是数组相邻2项的和
func work2() {
	a := [...]int{1, 4, 9, 16, 2, 5, 10, 15} //a数组
	fmt.Println("数组：", a)
	a1 := make([]int, len(a)-1)     //a1切片，且长度比a数组少一个
	for i := 0; i < len(a)-1; i++ { //利用a数组长度少一个循环，a数组相邻2项的和加入a1切片
		a1[i] = a[i] + a[i+1]
	}
	fmt.Println("切片：", a1)
}

// 数字重复统计
func work3() {
	r := rand.New(rand.NewSource(time.Now().UnixNano())) //生成随机数
	n := make([]int, 0, 100)                             //n切片，长度为100
	for i := 0; i < 100; i++ {
		nn := r.Intn(401) - 200 //[-200, 200]之间的随机数
		n = append(n, nn)       //100个[-200, 200]之间的随机数，加进n
	}
	sort.Ints(n) //数组n排序
	// fmt.Println(n)
	keys := make([]int, 0, 100)
	c := make(map[int]int) //定义一个新切片c
	for _, v := range n {  // 从n[0]开始取随机数，首先判断n keys中是否有该随机数，没有则添加key，并value = 1; 否则， value ++;
		if _, ok := c[v]; !ok {
			c[v] = 1
			keys = append(keys, v)
		} else {
			c[v]++
		}
	}
	sort.Ints(keys)


	for i, v := range keys {
		fmt.Println(keys[i], "出现：", c[v], "次")
	}
}

func main() {
	fmt.Println("第一题：看下面一段程序，回答问题")
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~")
	work1()
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~")
	fmt.Println("第二题：有一个数组 [1,4,9,16,2,5,10,15]，生成一个新切片，要求新切片元素是数组相邻2项的和")
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~")
	work2()
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~")
	fmt.Println("第三题：数字重复统计")
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~")
	work3()
	fmt.Println("~~~~~~~~~~~~~~~~~~~~~~~~~")
}